package com.motong.gongdan.job;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.motong.gongdan.config.wechat.ConfigurationService;
import com.motong.gongdan.entity.CustomEvent;
import com.motong.gongdan.entity.Departments;
import com.motong.gongdan.entity.EventLog;
import com.motong.gongdan.entity.User;
import com.motong.gongdan.service.*;
import com.motong.gongdan.util.LoginUtil;
import com.motong.gongdan.util.RedisUtil;
import com.motong.gongdan.util.StringUtil;
import com.motong.gongdan.vo.system.otherVo.WorkOrderListVo;
import com.motong.gongdan.vo.customEvent.SearchVo;
import com.motong.gongdan.vo.resp.StatisticsNumResp;
import com.motong.gongdan.vo.resp.WorkOrderResp;
import com.motong.gongdan.vo.system.CustomEvent.WorkOrderEventMsg;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author:fff
 * @time:2022/6/24
 */
@Slf4j
public class GroupSchedulerTask extends QuartzJobBean {
    @Resource
    CustomEventService customEventService;
    @Resource
    UserService userService;
    @Resource
    ConfigurationService configurationService;
    @Resource
    EventLogService eventLogService;
    @Resource
    WorkOrderService workOrderService;
    @Resource
    DepartmentsService departmentsService;

    @Override
    protected void executeInternal(JobExecutionContext context) {
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        if (jobDataMap != null && jobDataMap.get("eventId") != null) {






            try {
                LoginUtil.setIgnoreFactory(true);
                CustomEvent ce = customEventService.getById(jobDataMap.getIntValue("eventId"));
                LoginUtil.setIgnoreFactory(false);
                if (ce != null) {
                    LoginUtil.setLoginUserFactory(ce.getFactoryId());
                    WorkOrderListVo vo = new WorkOrderListVo();
                    if (StringUtil.isNotBlank(ce.getSearchCondition())) {
                        List<SearchVo> searchVos = JSONUtil.toList(ce.getSearchCondition(), SearchVo.class);
                        Map<String, Object> stringObjectHashMap = new HashMap<>();
                        Map<Integer, String> customFieldMap = new HashMap<>();
                        searchVos.forEach(i -> {
                            if (i.getFieldId() instanceof Integer) {
                                if (Objects.nonNull(i.getFieldValue()) && i.getFieldValue() instanceof List) {
                                    String value = ((List<?>) i.getFieldValue()).stream().map(Object::toString).collect(Collectors.joining(","));
                                    customFieldMap.put((Integer) i.getFieldId(), value);
                                } else if (Objects.nonNull(i.getFieldValue())) {
                                    customFieldMap.put((Integer) i.getFieldId(), i.getFieldValue().toString());
                                }
                            } else {
                                if (Objects.nonNull(i.getFieldValue()) && i.getFieldValue() instanceof List) {
                                    if (((List<?>) i.getFieldValue()).size() > 1) {
                                        stringObjectHashMap.put(i.getFieldId().toString().concat("Down"),((List<?>) i.getFieldValue()).get(0));
                                        stringObjectHashMap.put(i.getFieldId().toString().concat("Start"),((List<?>) i.getFieldValue()).get(0));
                                        stringObjectHashMap.put(i.getFieldId().toString().concat("Up"),((List<?>) i.getFieldValue()).get(1));
                                        stringObjectHashMap.put(i.getFieldId().toString().concat("End"),((List<?>) i.getFieldValue()).get(1));
                                    }
                                } else if (Objects.nonNull(i.getFieldValue())) {
                                    stringObjectHashMap.put(i.getFieldId().toString(), i.getFieldValue().toString());
                                }
                            }
                        });
                        BeanUtil.fillBeanWithMap(stringObjectHashMap, vo, true);
                        vo.setCustomFieldMap(customFieldMap);
                    }
                    JSONObject jsonObject = JSON.parseObject(ce.getPushMess());
                    WorkOrderEventMsg msg = jsonObject.toJavaObject(WorkOrderEventMsg.class);
                    List<WorkOrderResp> dataList = workOrderService.getEventSearchResult(vo);
                    if (StringUtil.isNotBlank(ce.getStatisticsData())) {
                        Map<String, Object> newMap = new HashMap<>();
                        Map<String, Object> defaultMap = getDefaultMap();
                        Map<String, Object> dataMap = JSONObject.parseObject(ce.getStatisticsData());
                        List<Object> valueList = Arrays.stream(dataMap.values().toArray()).filter(f -> StringUtil.isNotBlank(f.toString())).collect(Collectors.toList());
                        if (!CollectionUtils.isEmpty(valueList)) {
                            dataMap.keySet().forEach(k -> {
                                if (dataMap.get(k) != null && !"".equals(dataMap.get(k))) {
                                    String value = dataMap.get(k).toString();
                                    for (String s : defaultMap.keySet()) {
                                        value = value.replace(s, defaultMap.get(s).toString());
                                    }
                                    newMap.put(String.valueOf(k), value);
                                }
                            });
                        }
                        if (StringUtil.isNotBlank(msg.getComment())) {
                            List<Integer> woIds = new ArrayList<>();
                            if (!CollectionUtils.isEmpty(dataList)) {
                                woIds = dataList.stream().map(WorkOrderResp::getId).collect(Collectors.toList());
                            }
                            AtomicReference<String> comment = new AtomicReference<>(msg.getComment());
                            List<Integer> finalWoIds = woIds;
                            if (!newMap.isEmpty()) {
                                newMap.keySet().forEach(d -> {
                                    if (!CollectionUtils.isEmpty(finalWoIds)) {
                                        StatisticsNumResp snr = new StatisticsNumResp();
                                        if (!CollectionUtils.isEmpty(finalWoIds)) {
                                            snr = workOrderService.getBaseMapper().getEventStatistics(newMap.get(d).toString(), finalWoIds);
                                        }
                                        if (snr != null) {
                                            comment.set(comment.get().replace(d, snr.getResult().toString()));
                                        } else {
                                            comment.set(comment.get().replace(d, "0"));
                                        }
                                    }
                                });
                                msg.setComment(comment.get());
                            }
                        }
                    }
                    String token = (String) RedisUtil.get("access_token");
                    if (StringUtil.isBlank(token)) {
                        cn.hutool.json.JSONObject jo = configurationService.getAccessToken();
                        token = jo.getStr("access_token");
                    }
                    List<String> ids = new ArrayList<>();
                    if (StringUtil.isNotBlank(ce.getUserId())) {
                        ids.addAll(Arrays.asList(ce.getUserId().split(",")));
                    }
                    if (StringUtil.isNotBlank(ce.getDepId())) {
                        Arrays.asList(ce.getDepId().split(",")).forEach(d -> {
                            Departments departments = departmentsService.getById(Integer.valueOf(d));
                            if (departments != null) {
                                ids.addAll(Arrays.asList(departments.getIds().split(",")));
                            }
                        });
                    }
                    EventLog el = new EventLog();
                    AtomicReference<String> msgR = new AtomicReference<>("");
                    if (!CollectionUtils.isEmpty(ids)) {
                        String finalToken = token;
                        ids.forEach(u -> {
                            User user = userService.getById(u);
                            if (StringUtil.isNotBlank(user.getOpenid())) {
                                msgR.set(configurationService.sendMsgWorkOrder(msg, user.getOpenid(), finalToken));
                            }
                        });
                    }
                    if (StringUtil.isNotBlank(msgR.get())) {
                        el.setState(0);
                    } else {
                        el.setState(1);
                    }
                    el.setEventId(ce.getId());
                    el.setMsg(msgR.get());
                    el.setTime(new Date());
                    eventLogService.save(el);
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                LoginUtil.removeIgnoreFactory();
                LoginUtil.removeLoginUserFactory();
            }


        }
    }

    public Map<String, Object> getDefaultMap() {
        Map<String, Object> map = new HashMap<>();
        map.put("${工单.工单编号}", "w.code");
        map.put("${工单.产品编号}", "p.code");
        map.put("${工单.产品名称}", "p.name");
        map.put("${工单.产品规格}", "p.specification");
        map.put("${工单.工单状态}", "w.state");
        map.put("${工单.计划开始时间}", "w.start_time");
        map.put("${工单.计划结束时间}", "w.end_time");
        map.put("${工单.计划数}", "w.planed_number");
        map.put("${工单.良品数}", "w.good_product_number");
        map.put("${工单.不良品数}", "w.bad_product_number");
        map.put("${工单.实际开始时间}", "w.actual_start_time");
        map.put("${工单.实际结束时间}", "w.actual_end_time");
        return map;
    }

    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        map.put("${工单.统计数据4}", "");
        map.put("${工单.统计数据3}", "");
        map.put("${工单.统计数据2}", "");
        map.put("${工单.统计数据1}", "count(${工单.计划数})");
        map.keySet().forEach(k -> {
            if (map.get(k) != null && !map.get(k).equals("")) {
                System.out.println(map.get(k));
            }
        });

//        Map<String,Object> newMap =
//        map.entrySet().stream().filter(entry->entry.getValue()!=null && !entry.getValue().equals("")).collect(LinkedHashMap::new,(m,e)->m.put(e.getKey(),e.getValue()),LinkedHashMap::putAll);
//        System.out.println(newMap);
    }
}
